#include "simple_kws.h"
#include "speech_recognizer.h"
#include <string.h>
#include <stdio.h>

// Global variables for KWS state (static to this file)
static struct speech_rec g_local_speech_rec;
static bool g_local_kws_initialized = false;
static bool g_local_kws_running = false;

// User-provided callbacks
static kws_keyword_detected_callback g_on_keyword_detected = nullptr;
static kws_error_callback g_on_error = nullptr;

// Internal callback functions for speech_recognizer
static void local_on_result(const char *result, char is_last) {
    if (result && g_on_keyword_detected) {
        g_on_keyword_detected(result);
    }
}

static void local_on_speech_begin() {
    // Optional: Add logging here
}

static void local_on_speech_end(int reason) {
    if (reason != 0 && g_on_error) {
        char error_msg[256];
        snprintf(error_msg, sizeof(error_msg), "Speech end with error: %d", reason);
        g_on_error(error_msg);
    }
}

int simple_kws_init(const char* resource_path, int keyword_count,
                    kws_keyword_detected_callback on_detected,
                    kws_error_callback on_error) {
    if (g_local_kws_initialized) {
        return 0;
    }

    g_on_keyword_detected = on_detected;
    g_on_error = on_error;

    memset(&g_local_speech_rec, 0, sizeof(struct speech_rec));
    g_local_speech_rec.notif.on_result = local_on_result;
    g_local_speech_rec.notif.on_speech_begin = local_on_speech_begin;
    g_local_speech_rec.notif.on_speech_end = local_on_speech_end;

    // Note: resource_path is not directly used by sr_init, but by AIKIT_LoadData
    // which is handled in the main application or IvwQtInterface.
    int ret = sr_init(&g_local_speech_rec, keyword_count, SR_MIC);
    if (ret != 0) {
        if (g_on_error) {
            char error_msg[256];
            snprintf(error_msg, sizeof(error_msg), "sr_init failed with error: %d", ret);
            g_on_error(error_msg);
        }
        return -1;
    }

    g_local_kws_initialized = true;
    return 0;
}

int simple_kws_start() {
    if (!g_local_kws_initialized || g_local_kws_running) {
        return 0;
    }

    int ret = sr_start_listening(&g_local_speech_rec);
    if (ret != 0) {
        if (g_on_error) {
            char error_msg[256];
            snprintf(error_msg, sizeof(error_msg), "sr_start_listening failed with error: %d", ret);
            g_on_error(error_msg);
        }
        return -1;
    }

    g_local_kws_running = true;
    return 0;
}

int simple_kws_stop() {
    if (!g_local_kws_running) {
        return 0;
    }

    int ret = sr_stop_listening(&g_local_speech_rec);
    g_local_kws_running = false;
    return ret;
}

void simple_kws_cleanup() {
    if (g_local_kws_running) {
        simple_kws_stop();
    }

    if (g_local_kws_initialized) {
        sr_uninit(&g_local_speech_rec);
        g_local_kws_initialized = false;
    }
    g_on_keyword_detected = nullptr;
    g_on_error = nullptr;
}
